package com.pb.wkflow.core.config;

import com.pb.wkflow.api.exception.ApprovalException;
import com.pb.wkflow.core.factor.MyBpmnParseFactory;
import com.pb.wkflow.core.listener.CamundaGlobalListenerPlugin;
import com.pb.wkflow.core.utils.SnowFlakeUuidGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
import org.camunda.bpm.engine.spring.SpringTransactionContextFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * org.camunda.bpm.spring.boot.starter.CamundaBpmAutoConfiguration
 * @author 苗益辉
 * @date 2022/5/6 16:40
 */
@Slf4j
@Component
public class MySpringProcessEngineConfiguration extends SpringProcessEngineConfiguration {

    @Value("${camunda.tablePrefix:PBWK.}")
    private String tablePrefix;

    @Override
    protected void init() {
        //加载全局自定义监听插件
        List<ProcessEnginePlugin> processEnginePlugins = new ArrayList<>();
        processEnginePlugins.add(new CamundaGlobalListenerPlugin());
        super.setProcessEnginePlugins(processEnginePlugins);

        //加载自定义bpmn解析器
        MyBpmnParseFactory myBpmnParseFactory = new MyBpmnParseFactory();
        super.setBpmnParseFactory(myBpmnParseFactory);

        //设置uuid创建方式
        super.setIdGenerator(new SnowFlakeUuidGenerator());
        //关闭每15分钟的日志记录 PBWK.ACT_RU_METER_LOG
        //super.setMetricsEnabled(false);
        super.init();
    }

    @Override
    protected void initDataSource() {
        if(this.dataSource == null) {
            this.dataSource = new TransactionAwareDataSourceProxy(super.applicationContext.getBean(DataSource.class));
        }
        super.setDatabaseTablePrefix(tablePrefix);
        super.setTransactionManager(new DataSourceTransactionManager(this.dataSource));
        super.setTransactionContextFactory(new SpringTransactionContextFactory(this.transactionManager));
        super.initDataSource();
    }

    @Override
    protected InputStream getMyBatisXmlConfigurationSteam() {
        InputStream inputStream = this.getClass().getResourceAsStream("/spring/mapping.xml");
        String text = null;
        try{
            assert inputStream != null;
            text = IOUtils.toString(inputStream);
        }catch (IOException e) {
            log.error("{}", e);
            throw new ApprovalException(e.getMessage());
        }
        return IOUtils.toInputStream(text);
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}
